﻿/*
 * Copyright © 2020, Wuxi Safover Intelligent Technology Co., Ltd. All rights reserved.
 * 
 * 无锡安永智能科技有限公司版权所有，未经许可，不得用于商业用途
 * 
 * Visit: https://www.safover.com/ 
 */

using System;
using Safover.LidarCollector.Config;

namespace Safover.LidarCollector.Core
{
    public abstract class OpticalMaserDevice : SerialPortDevice, IOpticalMaserDeviceControllable, IOpticalMaser
    {
        private BaseOpticalMaserController CurrentController { get; set; }

        private BaseOpticalMaserController ClosedStateController { get; }

        private BaseOpticalMaserController OpenedStateController { get; }

        private BaseOpticalMaserController IrradiatingStateController { get; }

        public OpticalMaserStatus Status => CurrentController.OpticalMaserStatus;

        public abstract bool StartLasar();
        public abstract bool StopLasar();
        public abstract void ErrorReset();


        public bool CanOpen => CurrentController.CanOpen;

        public bool CanClose => CurrentController.CanClose;

        public bool CanOperate => CurrentController.CanOperate;

        /// <summary>
        /// 内触发频率
        /// </summary>
        public double? InternalTriggerFrequency { get; protected set; }

        /// <summary>
        /// 电流实际值
        /// </summary>
        public double? ElectricityRealValue { get; protected set; }

        /// <summary>
        /// LD温度
        /// </summary>
        public double? LDTemperature { get; protected set; }

        /// <summary>
        /// 激光晶体温度
        /// </summary>
        public double? LaserCrystalTemperature { get; protected set; }

        /// <summary>
        /// 倍晶体温度
        /// </summary>
        public double? FrequencyDoublingCrystalTemperature { get; protected set; }

        /// <summary>
        /// 激光器工作时长
        /// </summary>
        public TimeSpan? LaserWorkingTime { get; protected set; }

        /// <summary>
        /// 激光器是否开启发光
        /// </summary>
        public bool IsLaserOpened { get; set; }

        public OpticalMaserDevice()
        {
            ClosedStateController = new OpticalMaserClosedStateController(this);

            OpenedStateController = new OpticalMaserOpenedStateController(this);

            IrradiatingStateController = new OpticalMaserIrradiatingStateController(this);

            CurrentController = ClosedStateController;
        }

        protected override void ResetSerialPortParameters()
        {
            PortName = RuntimeConfigManager.Instance.OpticalMaserConfig.PortName;
            BaudRate = RuntimeConfigManager.Instance.OpticalMaserConfig.BaudRate;
        }

        internal void SetStatus(OpticalMaserStatus status)
        {
            switch (status)
            {
                case OpticalMaserStatus.Closed:
                    CurrentController = ClosedStateController;
                    break;
                case OpticalMaserStatus.Opened:
                    CurrentController = OpenedStateController;
                    break;
                case OpticalMaserStatus.Irradiating:
                    CurrentController = IrradiatingStateController;
                    break;
                default:
                    throw new InvalidOperationException($"Illegal device status = [{status}].");
            }
        }

        bool IOpticalMaserDeviceControllable.TryClose()
        {
            return CurrentController.CanClose && CurrentController.TryClose();
        }

        bool IOpticalMaserDeviceControllable.TryOpen()
        {
            return CurrentController.CanOpen && CurrentController.TryOpen();
        }

        void IOpticalMaserDeviceControllable.TryStartLazar()
        {
            if (CurrentController.CanOperate)
            {
                CurrentController.TryStartLazar();
            }
        }

        void IOpticalMaserDeviceControllable.TryStopLazar()
        {
            if (CurrentController.CanOperate)
            {
                CurrentController.TryStopLazar();
            }
        }

        void IOpticalMaserDeviceControllable.TryErrorReset()
        {
            if (CurrentController.CanOperate)
            {
                CurrentController.TryErrorReset();
            }
        }
    }
}
